﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using Golos.Helper;
using Golos.Http;

namespace Golos.BackEnd.Client
{
    public class TagsClient : HttpClientBase
    {
        public TagsClient(Uri serverUri) : base(serverUri)
        {
        }

        public TagsClient()
        {
            serverUri = new Uri(string.Format("http://{0}/", Topology.GetEndPoint(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"settings\topology\tags"))));
        }

        public bool AddNewTag(Guid questionId, List<string> tags)
        {
            try
            {
                byte[] data = new byte[0];
                using (MemoryStream stream = new MemoryStream())
                {
                    using (StreamWriter writer = new StreamWriter(stream))
                    {
                        foreach (string tag in tags)
                        {
                            writer.WriteLine(tag);
                        }
                        writer.Flush();
                    }
                    data = stream.ToArray();
                }
                var response = TrySendRequest(string.Format("?operation=addtags&questionid={0}", questionId), "POST", data);
                return response != null && response.StatusCode == HttpStatusCode.OK;
            }
            catch (Exception exception)
            {
                LogClass.WriteErrorEntry("Can't add new tag {0}", exception.ToString());
                return false;
            }
        }

        public List<Guid> SearchQuestions(string tag)
        {
            var response = TrySendRequest(string.Format("?operation=search&tag={0}", Convert.ToBase64String(Encoding.UTF8.GetBytes(tag))), "GET");
            if (response.ResponseStream == null || response.StatusCode != HttpStatusCode.OK)
                return new List<Guid>();
            List<Guid> result = new List<Guid>();
            using (Stream stream = response.ResponseStream)
            {
                using (StreamReader reader = new StreamReader(stream))
                {
                    while (!reader.EndOfStream)
                    {
                        string questionId = reader.ReadLine();
                        if (string.IsNullOrEmpty(questionId))
                            continue;
                        result.Add(new Guid(questionId));
                    }
                }
            }
            return result;
        }

        public List<string> GetQuestionTags(Guid questionId)
        {
            var response = TrySendRequest(string.Format("?operation=questiontags&questionid={0}", questionId), "GET");
            if (response.ResponseStream == null || response.StatusCode != HttpStatusCode.OK)
                return new List<string>();
            List<string> result = new List<string>();
            using (Stream stream = response.ResponseStream)
            {
                using (StreamReader reader = new StreamReader(stream))
                {
                    while (!reader.EndOfStream)
                    {
                        string tag = reader.ReadLine();
                        if (string.IsNullOrEmpty(tag))
                            continue;
                        result.Add(tag);
                    }
                }
            }
            return result;
        }

        public List<string> GetAllTags()
        {
            var response = TrySendRequest(string.Format("?operation=alltags"), "GET");
            if (response.ResponseStream == null || response.StatusCode != HttpStatusCode.OK)
                return new List<string>();
            List<string> result = new List<string>();
            using (Stream stream = response.ResponseStream)
            {
                using (StreamReader reader = new StreamReader(stream))
                {
                    while (!reader.EndOfStream)
                    {
                        string tag = reader.ReadLine();
                        if (string.IsNullOrEmpty(tag))
                            continue;
                        result.Add(tag);
                    }
                }
            }
            return result;
        }

        public List<string> GetPopularTags()
        {
            var response = TrySendRequest(string.Format("?operation=populartags"), "GET");
            if (response.ResponseStream == null || response.StatusCode != HttpStatusCode.OK)
                return new List<string>();
            List<string> result = new List<string>();
            using (Stream stream = response.ResponseStream)
            {
                using (StreamReader reader = new StreamReader(stream))
                {
                    while (!reader.EndOfStream)
                    {
                        string tag = reader.ReadLine();
                        if (string.IsNullOrEmpty(tag))
                            continue;
                        result.Add(tag);
                    }
                }
            }
            return result;
        }

        public bool RemoveQuestionTags(Guid questionId)
        {
            try
            {
                var response = TrySendRequest(string.Format("?operation=removequestiontags&questionid={0}", questionId), "DELETE");
                return response != null && response.StatusCode == HttpStatusCode.OK;
            }
            catch (Exception exception)
            {
                LogClass.WriteErrorEntry("Can't remove question tags {0}", exception.ToString());
                return false;
            }
        }
    }
}
